﻿using Furion.CMS.Application;
using Furion.DatabaseAccessor;
using Furion.DependencyInjection;
using Furion.Logging.Extensions;
using Furion.TaskScheduler;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Server.Kestrel.Core;
using Microsoft.Extensions.DependencyInjection;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Furion.CMS.Web.Core
{
    /// <summary>
    /// CMS Web应用核心启动配置
    /// </summary>
    [AppStartup(98)]
    public sealed class WebCoreStartup : AppStartup
    {
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddJwt<JwtHandler>();
            // 启用跨域
            services.AddCorsAccessor();

            services.AddControllersWithViews()
                .AddInjectWithUnifyResult<StatusCodeResultProvider>()
                .AddNewtonsoftJson(options =>
                {
                    options.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
                    // 采用时间区域转换器处理时间格式化
                    options.SerializerSettings.Converters.Add(new DateTimeZoneConverter());
                    options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
                })
                .AddDataValidation();

            services.AddMvcFilter<RequestAuditFilter>();

            // 启用事件源服务(前端通知推送)
            services.AddEventSourceService(true);
        }

        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            // 添加规范化结果状态码，需要在这里注册
            app.UseUnifyResultStatusCodes();

            app.UseInject();

            App.GetService<GlobalCacheBootLoader>()?
                .LoadPermissionCacheByResourcesAsync();

            // 异步启动Jobs 延迟3s
            SpareTime.DoIt(() =>
            {
                // 创建作用域
                Scoped.Create((_, scope) =>
                {
                    var services = scope.ServiceProvider;

                    // 获取工作应用服务
                    var jobService = services.GetService<Application.Services.CrontabAppService>();

                    // 获取数据库上下文
                    var dbContext = Db.GetDbContext(services);

                    // 获取仓储
                    var taskRepository = Db.GetRepository<Domain.CrontabInfo>(services);

                    // 读取已启用任务
                    var enableJobs = taskRepository.AsQueryable(false).Where(t => t.Enable)
                    .OrderByDescending(o=>o.CreatedTime)
                    .ToList()
                    .DistinctBy(d => d.InstancePath);

                    // 循环载入Job
                    foreach (var job in enableJobs)
                    {
                        jobService.Start(job.Id);
                    }
                });
            }, 3000);
        }
    }
}
